﻿#ifndef PST_INFOMATIONGRAPH3DBASICAL_H
#define PST_INFOMATIONGRAPH3DBASICAL_H

#include <QObject>
#include "PostEnumType.h"
#include "Parser/jsonDef.h"
#include "FieldGraphGenerator.h"
#include <vtkSmartPointer.h>
#include <vtkTable.h>
#include <vtkActor.h>
#include "BaseModule/GlobalHelper.h"
#include "ThreeDCloudMapSettingData.h"
#include "SurfaceElectricFieldMapSettingData.h"
#include "ThreeDSurfacePlotSettingData.h"
#include "Graph3DWindowBase.h"
#include "PoseSettingData.h"
#include "ThreeDCloudMapSidebarData.h"
#include "ThreeDSurfacePlotSidebarData.h"
#include "SurfaceElectricFieldMapSidebarData.h"
#include "TableChartWindowSidebarData.h"
#include "DataManager/WindowTotalData.h"
#include "DataManager/ProjectTreeData.h"

class vtkXMLUnstructuredGridReader;
class vtkScalarBarActor;
class vtkActor;
class vtkObject;
class vtkPointSet;

namespace pst
{
    class Graph3DWindowBase;
    class WidgetCutter;
    class FieldGraphGenerator;
    class FarFieldDataGenerator;
    class NearFieldDataGenerator;
    class ThreeDCloudMapSidebarData;
    class DataClipperGenerator;
    class PoseSettingData;
    class GeomtryActorGenerator;
    class DataClipperFilter;
    class DataTransformFilter;
    class FieldScalarBarGenerator;
    class ThreeDSurfacePlotSidebarData;
    class SurfaceElectricFieldMapSidebarData;

    class InfomationGraph3DBasical : public QObject
    {
        Q_OBJECT

    public:
        InfomationGraph3DBasical(QObject* parent = nullptr) : QObject(parent) {}

        /// @brief 文件写出至工程文件
        QDomElement& writeToProjectFile(QDomDocument* doc, QDomElement* element, GraphType graphType, bool isdiso = false)
        {
            QDomElement _InfomationGraph3DBasicalRoot = doc->createElement("InfomationGraph3DBasical");
            QDomAttr idattr = doc->createAttribute("InfoID");
            idattr.setValue(QString::number(m_informationID));
            _InfomationGraph3DBasicalRoot.setAttributeNode(idattr);

            int _itemID = -1;
            if (m_projectTreeSourceItem != nullptr)
            {
                if (!m_projectTreeSourceItem->data(Qt::UserRole + 10).isNull())
                    _itemID = m_projectTreeSourceItem->data(Qt::UserRole + 10).toInt();
            }
            QDomAttr ProjectTreeSourceItemIDattr = doc->createAttribute("ProjectTreeSourceItemID");
            ProjectTreeSourceItemIDattr.setValue(QString::number(_itemID));
            _InfomationGraph3DBasicalRoot.setAttributeNode(ProjectTreeSourceItemIDattr);

            QDomAttr CurrentFrequencyIndexattr = doc->createAttribute("CurrentFrequencyIndex");
            CurrentFrequencyIndexattr.setValue(QString::number(m_currentFrequencyIndex));
            _InfomationGraph3DBasicalRoot.setAttributeNode(CurrentFrequencyIndexattr);
            QDomAttr ValueGroupNameIndexattr = doc->createAttribute("ValueGroupNameIndex");
            ValueGroupNameIndexattr.setValue(QString::number(m_valueGroupNameIndex));
            _InfomationGraph3DBasicalRoot.setAttributeNode(ValueGroupNameIndexattr);
            QDomAttr ValueComponentIndexattr = doc->createAttribute("ValueComponentIndex");
            ValueComponentIndexattr.setValue(QString::number(m_valueComponentIndex));
            _InfomationGraph3DBasicalRoot.setAttributeNode(ValueComponentIndexattr);

            QDomAttr GeometryFileNameattr = doc->createAttribute("GeometryFileName");
            GeometryFileNameattr.setValue(m_geometryFileName.join(";"));
            _InfomationGraph3DBasicalRoot.setAttributeNode(GeometryFileNameattr);

            GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "FilePath", m_filePath);        
            if (m_graph != nullptr)
                GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "AddedGraphID", QString::number(m_graph->getWindowUniversalID()));
            GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "GraphType", QString::number((int)m_graphType));
            GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "Name", m_name);
            GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "IsLog", QString::number(m_isLog));
            GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "CurrentScalarArrayComp", QString::number(m_currentScalarArrayComp));
            GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "CurrentAnimationIndex", QString::number(m_currentAnimationIndex));
            GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "LastFrameIndexBeforeExportAnimation", QString::number(m_lastFrameIndexBeforeExportAnimation));
            GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "IsGraphRenamed", QString::number(m_isGraphRenamed));
            GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "InformationID", QString::number(m_informationID));
            GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "ReaderIndex", QString::number(readerIndex));
            GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "ResultDataIndex", QString::number(resultDataIndex));
            GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "ReaderType", readerType);
            GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "IsGeomtryActorImported", QString::number(m_isGeomtryActorImported));
            GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "DataSources", m_dataSources);
            GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "FieldType", QString::number(m_fieldType));
            GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "Unit", m_unit);
            auto _varValueListStr = GlobalHelperInstance->convertDoubleListToQString(m_VarValueList);
            GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "VarValueList", _varValueListStr);
            GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "ResultType", QString::number(m_resultType));
            GlobalHelperInstance->createDomElement(doc, &_InfomationGraph3DBasicalRoot, "GraphIDFromType", QString::number(m_graphIDFromType));


            element->appendChild(_InfomationGraph3DBasicalRoot);

            if (graphType == GraphType::ThreeDCloudMap)
            {
                m_threeDCloudMapSettingData->writeToProjectFile(doc, &_InfomationGraph3DBasicalRoot, isdiso);
                m_TDCMSidebarData->writeToProjectFile(doc, &_InfomationGraph3DBasicalRoot, isdiso);
            }
            else if (graphType == GraphType::ThreeDSurfacePlot)
            {
                m_threeDSurfacePlotSettingData->writeToProjectFile(doc, &_InfomationGraph3DBasicalRoot, isdiso);
                m_TDSPSidebarData->writeToProjectFile(doc, &_InfomationGraph3DBasicalRoot, isdiso);
                m_poseSettingData->writeToProjectFile(doc, &_InfomationGraph3DBasicalRoot, isdiso);//只有三维曲面图有
            }
            else if (graphType == GraphType::SurfaceElectricFieldMap)
            {
                m_surfaceElectricFieldMapSettingData->writeToProjectFile(doc, &_InfomationGraph3DBasicalRoot, isdiso);
                m_SEFMSidebarData->writeToProjectFile(doc, &_InfomationGraph3DBasicalRoot, isdiso);
            }
            else if (graphType == GraphType::TableChart)
            {
                m_TableChartWindowSidebarData->writeToProjectFile(doc, &_InfomationGraph3DBasicalRoot, isdiso);
            }

            return _InfomationGraph3DBasicalRoot;
        }
        /// @brief 从工程文件读入数据
        void readFromProjectFile(QDomElement* element, GraphType graphType, bool isdiso = false)
        {
            int infoID = element->attribute("InfoID").toInt();
            m_informationID = infoID;

            auto _FilePathNodeList = element->elementsByTagName("FilePath");
            m_filePath = _FilePathNodeList.item(0).toElement().text();

            auto isSuc =  GlobalHelperInstance->CurrentInstallationDirectoryPathConversion(m_filePath);

            auto _AddedGraphID = element->elementsByTagName("AddedGraphID").at(0).toElement().text().toInt();
            m_graph = WindowTotalDataInstance->getGraph3DWindowByID(_AddedGraphID);
            m_graphType = (GraphType)element->elementsByTagName("GraphType").at(0).toElement().text().toInt();
            m_name = element->elementsByTagName("Name").at(0).toElement().text();
            m_isLog = element->elementsByTagName("IsLog").at(0).toElement().text().toInt();
            m_currentScalarArrayComp = element->elementsByTagName("CurrentScalarArrayComp").at(0).toElement().text().toInt();
            m_currentAnimationIndex = element->elementsByTagName("CurrentAnimationIndex").at(0).toElement().text().toInt();
            m_lastFrameIndexBeforeExportAnimation = element->elementsByTagName("LastFrameIndexBeforeExportAnimation").at(0).toElement().text().toInt();
            m_isGraphRenamed = element->elementsByTagName("IsGraphRenamed").at(0).toElement().text().toInt();
            m_informationID = element->elementsByTagName("InformationID").at(0).toElement().text().toInt();
            readerIndex = element->elementsByTagName("ReaderIndex").at(0).toElement().text().toInt();
            resultDataIndex = element->elementsByTagName("ResultDataIndex").at(0).toElement().text().toInt();
            readerType = element->elementsByTagName("ReaderType").at(0).toElement().text();
            m_isGeomtryActorImported = element->elementsByTagName("IsGeomtryActorImported").at(0).toElement().text().toInt();
            m_dataSources = element->elementsByTagName("DataSources").at(0).toElement().text();
            m_fieldType = element->elementsByTagName("FieldType").at(0).toElement().text().toInt();
            m_unit = element->elementsByTagName("Unit").at(0).toElement().text();
            auto _varValueListStr = element->elementsByTagName("VarValueList").at(0).toElement().text();
            m_VarValueList = GlobalHelperInstance->convertStringToDoubleList(_varValueListStr);
            m_resultType = element->elementsByTagName("ResultType").at(0).toElement().text().toInt();
            m_graphIDFromType = element->elementsByTagName("GraphIDFromType").at(0).toElement().text().toInt();

            //做出相应移位动作？

            if (graphType == GraphType::ThreeDCloudMap)
            {
                m_threeDCloudMapSettingData->readFromProjectFile(&element->elementsByTagName("ThreeDCloudMapSettingData").at(0).toElement(), isdiso);
                m_TDCMSidebarData->readFromProjectFile(&element->elementsByTagName("ThreeDCloudMapSidebarData").at(0).toElement(), isdiso);
            }
            else if (graphType == GraphType::ThreeDSurfacePlot)
            {
                m_threeDSurfacePlotSettingData->readFromProjectFile(&element->elementsByTagName("ThreeDSurfacePlotSettingData").at(0).toElement(), isdiso);
                m_TDSPSidebarData->readFromProjectFile(&element->elementsByTagName("ThreeDSurfacePlotSidebarData").at(0).toElement(), isdiso);
                m_poseSettingData->readFromProjectFile(&element->elementsByTagName("PoseSettingData").at(0).toElement(), isdiso);
            }
            else if (graphType == GraphType::SurfaceElectricFieldMap)
            {
                m_surfaceElectricFieldMapSettingData->readFromProjectFile(&element->elementsByTagName("SurfaceElectricFieldMapSettingData").at(0).toElement(), isdiso);
                m_SEFMSidebarData->readFromProjectFile(&element->elementsByTagName("ThreeDSurfacePlotSidebarData").at(0).toElement(), isdiso);
            }
            else if (graphType == GraphType::TableChart)
            {
                m_TableChartWindowSidebarData->readFromProjectFile(&element->elementsByTagName("TableChartWindowSidebarData").at(0).toElement(), isdiso);
            }
        }

    public:
        QString m_filePath{};
        // vtkXMLUnstructuredGridReader* m_reader = nullptr;
        // vtkObject* m_reader = nullptr;
        void* m_reader = nullptr; // 后续需求确定后 应该改为具体类型
        vtkScalarBarActor* m_scalarBar = nullptr;
        vtkActor* m_actor = nullptr;
        Graph3DWindowBase* m_graph = nullptr;
        GraphType m_graphType = GraphType::None;
        vtkPointSet* m_data = nullptr;  
        int m_currentFrequencyIndex = 0;
        QString m_name{};
        FieldGraphGenerator* m_fieldGraphGenerator = nullptr;
        FieldScalarBarGenerator* m_fieldScalarBarGenerator = nullptr;
        ResultDataPointer m_resultData = nullptr;
        // WidgetCutter* m_widgetCutter = nullptr;
        int m_valueGroupNameIndex{ -1 }; // 对应的value下标
        int m_valueComponentIndex{ 0 };             // value的分量
        bool m_isLog{ false };
        FarFieldDataGenerator* m_farFieldDataGenerator = nullptr;
        NearFieldDataGenerator* m_nearFieldDataGenerator = nullptr;
        QList<FieldGraphGenerator::ArrayInformation> m_allPointArray{};
        QList<FieldGraphGenerator::ArrayInformation> m_allCellArray{};
        FieldGraphGenerator::ArrayInformation m_currentScalarArray{};
        int m_currentScalarArrayComp{0}; // 分量
        QList<vtkPointSet*> m_animationDataList;
        int m_currentAnimationIndex{ 0 };
        QList<vtkSmartPointer<vtkTable>> m_animationTableList;
        vtkSmartPointer<vtkTable> m_tableToExport = nullptr;    // 用于导出表格的表格，即用于当前显示的table
        DataClipperGenerator* m_dataClipperGenerator = nullptr; // 数据裁剪
        PoseSettingData* m_poseSettingData = nullptr;
        DataClipperFilter* m_dataClipperFilter = nullptr;
        DataTransformFilter* m_dataTransformFilter = nullptr;
        int m_lastFrameIndexBeforeExportAnimation{0}; // 动图导出前的最后一帧


        QListWidgetItem* m_sidebarItem = nullptr;//侧边栏名字item的指针
        ThreeDCloudMapSidebarData* m_TDCMSidebarData = nullptr;
        ThreeDSurfacePlotSidebarData* m_TDSPSidebarData = nullptr;
        SurfaceElectricFieldMapSidebarData* m_SEFMSidebarData = nullptr;
        TableChartWindowSidebarData* m_TableChartWindowSidebarData = nullptr;

        ThreeDCloudMapSettingData* m_threeDCloudMapSettingData = nullptr;
        SurfaceElectricFieldMapSettingData* m_surfaceElectricFieldMapSettingData = nullptr;
        ThreeDSurfacePlotSettingData* m_threeDSurfacePlotSettingData = nullptr;

        bool m_isGraphRenamed{ false };//图像是否有过重命名
    public:
        int m_informationID{0};
        int readerIndex{ -1 };
        int resultDataIndex{ -1 };
        QString readerType;
        bool m_isGeomtryActorImported = false;
        // vtkSmartPointer<vtkActor> m_geometryActor{ nullptr };
        GeomtryActorGenerator* m_geomtryActorGenerator{ nullptr };
        QStringList m_geometryFileName{};
        QString m_dataSources;
        int m_fieldType = 0; // 域类型：1：时域；2频域；0：无
        QString m_unit;
        QList<double> m_VarValueList;
        //文件结果参数类型 // 是文件的类型
        // 体电场分布（0）面电场分布（1） 点电场（探针点）（2） 表面场分布（3）表面电流密度（4） 空间电势分布（5）
        // 表面电势分布（6） 方向图（7）  S参数（8）  驻波比（9）  电压（10）
        // 电流（11） 附着点路径（14）   面电势分布（15） 干扰关联矩阵（12）  SAR（13）
        int m_resultType = 0; 
        int m_graphIDFromType = 1; // 每种图像类型后面对应的id .如 增益1，增益2，增益3、 电场1，电场2，电场3等
        QStandardItem* m_projectTreeSourceItem = nullptr;//该图像对应来源于那个工程树节点（文件）
    };
} // namespace pst

#endif
